/**
 * 访问器属性 装饰器
 * 和普通的实例方法的区别是：descriptor参数中多了get和set
 * 参数的区别：target: 没有静态只有一种了，key:已知都是string descriptor 里面携带的内容不大一致。
 * // 访问器属性方法 的descriptor
 * {
  get: [Function: get age],
  set: [Function: set age],
  enumerable: false,
  configurable: true
}
  // 实例普通属性方法 的descriptor
{
  value: [Function: info],
  writable: true,
  enumerable: false,
  configurable: true
}
 * @param str
 * @returns
 */
function Interceptor() {
  return function <T>(
    target: any,
    key: string,
    descriptor: TypedPropertyDescriptor<T>
  ) {
    // console.log(target, key, descriptor);
    const tmp = descriptor.set!;
    descriptor.set = function (value: T) {
      console.log("拦截处理");
      tmp.call(this, value);
      console.log("调用结束");
    };
  };
}

class User {
  public id: number;
  public name: string;
  private _age: number;
  // @d()
  info() {}
  @Interceptor()
  set age(v: number) {
    console.log("set age function load", v);
    this._age = v;
  }
  get age() {
    return this._age;
  }
}
const u = new User();
u.age = 10;

// 方法参数装饰器

// 1. 静态方法 为 类本身 实例属性  类原型
// 2. 字符串，表示方法名
// 3. 数字，表示参数顺序
function ParamDecorator(target: any, key: string, index: number) {
  console.log(target, key, index);
}
class A {
  method1(@ParamDecorator id: number, @ParamDecorator name: string) {}
}
const obj1 = new A();
obj1.method1(1, "jack");
